use axum::http::HeaderValue;
use hyper::{HeaderMap, Method};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Debug;

use crate::{BASE_URL, LOGIN_TOKEN};

#[derive(Debug, Clone)]
pub struct Request<REQ>
where
    REQ: Serialize + Clone + Debug,
{
    pub data: REQ,
    pub url: RequestUrl,
    pub headers: Option<HeaderMap>,
    pub content_type: RequestContentType,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum RequestContentType {
    Form,
    Json,
    Default,
}
impl Default for RequestContentType {
    fn default() -> Self {
        RequestContentType::Default
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum RequestUrl {
    GetConfigs,
    PostConfigLinsten,
    PostConfigs,
    DeleteConfigs,
    GetHistoryConfigs,
    GetHistoryConfigsInfo,
    GetHistoryPreviousConfigsInfo,
    PostServiceInstance,
    DeleteServiceInstance,
    PutServiceInstance,
    GetServiceInstanceList,
    GetServiceInstance,
    PutServiceInstanceBeat,
    PostService,
    DeleteService,
    PutService,
    GetService,
    GetServiceList,
    GetSysOperterSwitch,
    PutSysOperterSwitch,
    GetSysOperterMetrics,
    GetSysOperatorServers,
    GetSysRaftLeader,
    PutHealthInstance,
    PutMetaDataInstanceBatch,
    DeleteMetaDataInstanceBatch,
    GetConsoleNameSpaces,
    PostConsoleNameSpaces,
    PutConsoleNameSpaces,
    DeleteConsoleNameSpaces,
}

#[derive(Debug, Clone)]
pub struct Response {
    pub data: Option<String>,
    pub headers: Option<HashMap<String, HeaderValue>>,
}
// impl Copy for Response {}

#[derive(Debug, Clone)]
pub struct ConfigsRes {
    pub data: Option<String>,
    pub headers: Option<HashMap<String, HeaderValue>>,
}

impl Copy for RequestUrl {}

impl RequestUrl {
    pub async fn convert(&self) -> anyhow::Result<(String, Method)> {
        let base_url = BASE_URL.as_str();
        let token = LOGIN_TOKEN.lock().await;
        let access_token = &token.get("token").unwrap().access_token;
        match self {
            RequestUrl::GetConfigs => Ok((
                format!(
                    "{}/nacos/v1/cs/configs?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::PostConfigLinsten => Ok((
                format!(
                    "{}/nacos/v1/cs/configs/listener?accessToken={}",
                    base_url, access_token
                ),
                Method::POST,
            )),

            RequestUrl::PostConfigs => Ok((
                format!(
                    "{}/nacos/v1/cs/configs?accessToken={}",
                    base_url, access_token
                ),
                Method::POST,
            )),
            RequestUrl::DeleteConfigs => Ok((
                format!(
                    "{}/nacos/v1/cs/configs?accessToken={}",
                    base_url, access_token
                ),
                Method::DELETE,
            )),
            RequestUrl::GetHistoryConfigs => Ok((
                format!(
                    "{}/nacos/v1/cs/history?search=accurate&accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetHistoryConfigsInfo => Ok((
                format!(
                    "{}/nacos/v1/cs/history?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetHistoryPreviousConfigsInfo => Ok((
                format!(
                    "{}/nacos/v1/cs/history/previous?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::PostServiceInstance => Ok((
                format!(
                    "{}/nacos/v1/ns/instance?accessToken={}",
                    base_url, access_token
                ),
                Method::POST,
            )),
            RequestUrl::DeleteServiceInstance => Ok((
                format!(
                    "{}/nacos/v1/ns/instance?accessToken={}",
                    base_url, access_token
                ),
                Method::DELETE,
            )),
            RequestUrl::PutServiceInstance => Ok((
                format!(
                    "{}/nacos/v1/ns/instance?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::GetServiceInstanceList => Ok((
                format!(
                    "{}/nacos/v1/ns/instance/list?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetServiceInstance => Ok((
                format!(
                    "{}/nacos/v1/ns/instance?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::PutServiceInstanceBeat => Ok((
                format!(
                    "{}/nacos/v1/ns/instance/beat?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::PostService => Ok((
                format!(
                    "{}/nacos/v1/ns/service?accessToken={}",
                    base_url, access_token
                ),
                Method::POST,
            )),
            RequestUrl::DeleteService => Ok((
                format!(
                    "{}/nacos/v1/ns/service?accessToken={}",
                    base_url, access_token
                ),
                Method::DELETE,
            )),
            RequestUrl::PutService => Ok((
                format!(
                    "{}/nacos/v1/ns/service?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::GetService => Ok((
                format!(
                    "{}/nacos/v1/ns/service?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetServiceList => Ok((
                format!(
                    "{}/nacos/v1/ns/service/list?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetSysOperterSwitch => Ok((
                format!(
                    "{}/nacos/v1/ns/operator/switches?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::PutSysOperterSwitch => Ok((
                format!(
                    "{}/nacos/v1/ns/operator/switches?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::GetSysOperterMetrics => Ok((
                format!(
                    "{}/nacos/v1/ns/operator/metrics?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetSysOperatorServers => Ok((
                format!(
                    "{}/nacos/v1/ns/operator/servers?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::GetSysRaftLeader => Ok((
                format!(
                    "{}/nacos/v1/ns/raft/leader?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::PutHealthInstance => Ok((
                format!(
                    "{}/nacos/v1/ns/health/instance?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::PutMetaDataInstanceBatch => Ok((
                format!(
                    "{}/nacos/v1/ns/instance/metadata/batch?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::DeleteMetaDataInstanceBatch => Ok((
                format!(
                    "{}/nacos/v1/ns/instance/metadata/batch?accessToken={}",
                    base_url, access_token
                ),
                Method::DELETE,
            )),
            RequestUrl::GetConsoleNameSpaces => Ok((
                format!(
                    "{}/nacos/v1/console/namespaces?accessToken={}",
                    base_url, access_token
                ),
                Method::GET,
            )),
            RequestUrl::PostConsoleNameSpaces => Ok((
                format!(
                    "{}/nacos/v1/console/namespaces?accessToken={}",
                    base_url, access_token
                ),
                Method::POST,
            )),
            RequestUrl::PutConsoleNameSpaces => Ok((
                format!(
                    "{}/nacos/v1/console/namespaces?accessToken={}",
                    base_url, access_token
                ),
                Method::PUT,
            )),
            RequestUrl::DeleteConsoleNameSpaces => Ok((
                format!(
                    "{}/nacos/v1/console/namespaces?accessToken={}",
                    base_url, access_token
                ),
                Method::DELETE,
            )),
        }
    }
}
